//
//  PLine.m
//  ProjectL
//
//  Created by Nguyen Tan Loc on 8/16/13.
//  Copyright (c) 2013 Nguyen Tan Loc. All rights reserved.
//

#import "PLine.h"
#import "Utility.h"
#import "MainGameScene.h"

@implementation PLine
@synthesize _node = mNode;
@synthesize _inverse = mInverse;

-(id) initWithNode:(PNode *)node
{
    if (self = [super initWithFile:@"line.png"])
    {
        mVertices = (CGPoint *)calloc(8, sizeof(CGPoint));
        mCoordinates = (CGPoint *)calloc(8, sizeof(CGPoint));
        mColors = (ccColor4F *)calloc(8, sizeof(ccColor4F));

        mNode = node;
        mInverse = NO;
        
        [self setLineState:eLS_IDLE];
        [self setAnchorPoint:ccp(0., 0.0f)];
        
        [self setupVertice];
        [self updateRealtime];
        mState = eLS_IDLE;
    }
    
    return self;
}

-(void) setupVertice
{
    float size = uniPos(1, 2);
    mVertices[0] = ccp(-size, -size);
    mVertices[1] = ccp( size, -size);
    mVertices[2] = ccp(-size, -size);
    mVertices[3] = ccp( size, -size);
    mVertices[4] = ccp(-size, -size);
    mVertices[5] = ccp( size, -size);
    mVertices[6] = ccp(-size,  size);
    mVertices[7] = ccp( size,  size);
    
    mCoordinates[0] = ccp(0.0, 0.2);
    mCoordinates[1] = ccp(1.0, 0.2);
    mCoordinates[2] = ccp(0.0, 0.2);
    mCoordinates[3] = ccp(1.0, 0.2);
    mCoordinates[4] = ccp(0.0, 0.3);
    mCoordinates[5] = ccp(1.0, 0.3);
    mCoordinates[6] = ccp(0.0, 0.8);
    mCoordinates[7] = ccp(1.0, 0.8);

    float alpha = (float)(self.opacity) / 255.0f;
    [self setupColorWithAlpha:alpha];

    self.shaderProgram = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionTextureColor];
    [self.shaderProgram link]; 
    [self.shaderProgram updateUniforms];
}

-(void) setupColorWithAlpha:(float)alpha
{
    mColors[0] = ccc4f(1.0 * alpha, 1.0 * alpha, 1.0 * alpha, alpha);
    mColors[1] = ccc4f(1.0 * alpha, 1.0 * alpha, 1.0 * alpha, alpha);
    mColors[2] = ccc4f(1.0 * alpha, 1.0 * alpha, 1.0 * alpha, alpha);
    mColors[3] = ccc4f(1.0 * alpha, 1.0 * alpha, 1.0 * alpha, alpha);
    mColors[4] = ccc4f(1.0 * alpha, 1.0 * alpha, 1.0 * alpha, alpha);
    mColors[5] = ccc4f(1.0 * alpha, 1.0 * alpha, 1.0 * alpha, alpha);
    mColors[6] = ccc4f(1.0 * alpha, 1.0 * alpha, 1.0 * alpha, alpha);
    mColors[7] = ccc4f(1.0 * alpha, 1.0 * alpha, 1.0 * alpha, alpha);
}

-(void) setLineState:(eLineState)state
{
    self.opacity = state == eLS_IDLE ? 100 : 255;
    
    if (mState == eLS_SPREADED)
        return;
    
    mState = state;
    float alpha = (float)(self.opacity) / 255.0f;
    [self setupColorWithAlpha:alpha];
}

-(void) draw
{
    CC_NODE_DRAW_SETUP();
    
    ccGLEnableVertexAttribs(kCCVertexAttribFlag_Position | kCCVertexAttribFlag_Color | kCCVertexAttribFlag_TexCoords);
    ccGLBindTexture2D([self.texture name]);
    ccGLBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
    
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, mVertices);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, mCoordinates);
    glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_FLOAT, GL_FALSE, 0, mColors);
    
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
    
    CC_INCREMENT_GL_DRAWS(1);
}

-(void) updateLine
{
    CGPoint sub = ccpSub([mNode._nextNode getRealPosition], [mNode getRealPosition]);
    float angle = [[Utility getInstance] vectorToAngle:sub];
    if (mInverse)
    {
        angle += 180;
        [self setPosition:[mNode._nextNode getRealPosition]];
    }
    else
    {
        [self setPosition:[mNode getRealPosition]];
    }
    
    [self setLength:ccpLength(sub)];
    [self setRotation:angle];
}

-(void) setLength:(float)length
{
    mVertices[6].y = length;
    mVertices[7].y = length;
}

-(float) getLength
{
    CGPoint sub = ccpSub([mNode._nextNode getRealPosition], [mNode getRealPosition]);
    return ccpLength(sub);
}

-(void) spread
{
    CCLOG(@"line spread");
    mState = eLS_SPREADED;
    mVertices[2].y = 0;
    mVertices[3].y = 0;
    mVertices[4].y = 0;
    mVertices[5].y = 0;
    
    ccColor4F color = ccc4FFromccc3B(CL_RED);
//    ccColor4F color = ccc4f(0, 0, 0, 0);
    mColors[0] = color;
    mColors[1] = color;
    mColors[2] = color;
    mColors[3] = color;

    [self scheduleUpdate];
}

-(void) update:(ccTime)delta
{
    float length = [self getLength];
    float diff = PATH_LINE_SPREAD_SPEED * delta;

//    mVertices[2].y += diff;
//    mVertices[3].y = mVertices[2].y;
    mVertices[4].y += diff;
    mVertices[5].y = mVertices[4].y;
    
    if (mVertices[4].y > PATH_LINE_SPREAD_ALPHA_RANGE && mVertices[4].y < length)
    {
        mVertices[2].y = mVertices[4].y - PATH_LINE_SPREAD_ALPHA_RANGE;
        mVertices[3].y = mVertices[2].y;
    }
    else if (mVertices[4].y >= length)    // Done here
    {
        mVertices[4].y = length;
        mVertices[5].y = mVertices[4].y;
        mVertices[2].y += diff;
        mVertices[3].y = mVertices[2].y;
        
        if (mVertices[2].y >= length)
        {
            mVertices[2].y = mVertices[4].y;
            mVertices[3].y = mVertices[4].y;
            [self unscheduleUpdate];
            [self spreadDone];
        }
    }
    
//    if (mVertices[4].y >= length)
    
}

-(void) spreadDone
{
    if (mInverse)
    {
        CCLOG(@"You dead user node");
        [mNode spread];
    }
    else
    {
        [mNode._nextNode spread];
    }
}

-(void) reset
{
    CCLOG(@"line reset");
    [self unscheduleUpdate];
    [self setupColorWithAlpha:1];
    mVertices[2].y = 0;
    mVertices[3].y = 0;
    mVertices[4].y = 0;
    mVertices[5].y = 0;
}

-(CGPoint) getPosWithPercent:(float)percent
{
    CGPoint sub = ccpSub([mNode._nextNode getRealPosition], [mNode getRealPosition]);
    return ccp([mNode getRealPosition].x + sub.x * (percent / 100.0f), [mNode getRealPosition].y + sub.y * (percent / 100.0f));
}

-(void) updateRealtime
{
    [self schedule:@selector(updateLine)];
}

-(NSString *) getSpriteFrameName
{
    return @"";
}

-(void) dealloc
{
    free(mVertices);
    free(mCoordinates);
    free(mColors);
    
    [self stopAllActions];
    [super dealloc];
    
    CCLOG(@"PLine dealloc!");
}

@end
